/*
Copyright © 2024 wjsmc
*/
package internal

import (
	"fmt"
	"log"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/AlecAivazis/survey/v2"
	"github.com/fatih/color"
	"github.com/spf13/cobra"
	"nodemessage.com/ruov-cli/rlog"
	"nodemessage.com/ruov-cli/tpl"
	"nodemessage.com/ruov-cli/types"
	"nodemessage.com/ruov-cli/utils"
)

// useCmd represents the use command
var useCmd = &cobra.Command{
	Use:   "mod",
	Short: "新增 admin-api 项目子模块",
	Long:  color.New(color.FgYellow).Sprintf("在 admin-api 目录 [logic] module下新增一个模块"),
	Run: func(cmd *cobra.Command, args []string) {
		setterGenAll()
		// 校验是否为项目目录
		xmlConf := checkIsApiPath()
		// 读取logic模块pom文件
		pom := readLogicPom()
		// 准备项目信息
		mode, tabs := readyModInfo(xmlConf, pom)
		// 生成模板
		genTabTpl(xmlConf, []string{mode}, true, tabs)
	},
}

func readyModInfo(xmlConf types.Config, tplPom *types.TplLoginPom) (mode string, tabs []types.TableInfo) {
	tables, err := utils.DbGetDatabaseSchema(xmlConf.Database.Username,
		xmlConf.Database.Password,
		xmlConf.Database.Host,
		xmlConf.Database.Port,
		xmlConf.Database.DBName)
	if err != nil {
		rlog.Logger.Fatal("获取数据库结构失败:%v", err)
	}
	tab := utils.CollectMap(tables, func(i types.TableInfo) string {
		return i.Name
	})
	questions := []*survey.Question{
		{
			Name: "moduleName",
			Prompt: &survey.Input{
				Message: "模块名:",
			},
			Validate: survey.ComposeValidators(survey.Required, func(ans interface{}) error {
				re := regexp.MustCompile(`^[a-zA-Z-]+$`)
				if !re.MatchString(ans.(string)) {
					return fmt.Errorf("模块名只能包含[字母]和[-]")
				}
				if !strings.HasPrefix(ans.(string), logicDir) {
					ans = logicDir + "-" + ans.(string)
				}
				log.Println(filepath.Join(logicDir, ans.(string)))
				if utils.FilePathExists(filepath.Join(logicDir, ans.(string))) {
					return fmt.Errorf("模块已存在:%s", ans.(string))
				}
				return nil
			}),
		},
		{
			Name: "tables",
			Prompt: &survey.MultiSelect{
				Message:  "数据库:",
				Options:  tab,
				PageSize: 15,
			},
		},
	}
	answers := struct {
		ModuleName string
		Tables     []string
	}{}
	err = survey.Ask(questions, &answers)
	if err != nil {
		rlog.Logger.Fatal("填写信息失败:%v", err)
	}
	if !strings.HasPrefix(answers.ModuleName, logicDir) {
		answers.ModuleName = logicDir + "-" + answers.ModuleName
	}
	tplPom.Modules.Module = append(tplPom.Modules.Module, answers.ModuleName)
	javaDir := []string{logicDir, answers.ModuleName, "src", "main", "java"}
	javaDir = append(javaDir, strings.Split(xmlConf.BasePack, ".")...)
	javaDir = append(javaDir, strings.Split(strings.TrimLeft(answers.ModuleName, logicDir+"-"), "-")...)
	err = utils.FileCreateDirectories([]string{
		filepath.Join(logicDir, answers.ModuleName, "src", "main"),
		filepath.Join(javaDir...),
		filepath.Join(append(javaDir, "domain")...),
		filepath.Join(append(javaDir, "mapper")...),
		filepath.Join(append(javaDir, "service", "impl")...),
		filepath.Join(append(javaDir, "controller")...),
		filepath.Join(logicDir, answers.ModuleName, "src", "main", "resources", "mapper"),
	})
	err = utils.TplGenerateFromTemplate(filepath.Join(logicDir, answers.ModuleName, "pom.xml"),
		tpl.TemplateFS, "logic.pom.xml.vm",
		map[string]any{
			"ArtifactId": answers.ModuleName,
		})
	if err != nil {
		rlog.Logger.Fatal("pom模板文件生成失败:%v", err)
	}
	if err != nil {
		rlog.Logger.Fatal("创建目录失败:%v", err)
	}
	err = utils.XmlFileWriteXMLConfig(filepath.Join(logicDir, "pom.xml"), tplPom, PomHeader)
	if err != nil {
		rlog.Logger.Fatal("写入logic模块pom文件失败:%v", err)
	}
	mode = answers.ModuleName
	for _, t := range answers.Tables {
		for _, table := range tables {
			if table.Name == t {
				tabs = append(tabs, table)
			}
		}
	}
	return
}
